using Microsoft.AspNetCore.Mvc;
using Traceability.API.Dtos;
using Traceability.API.Services;
using Traceability.ErrorCode;

namespace Traceability.API.Controllers
{
    /// <summary>
    /// Redis测试控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class RedisTestController : ControllerBase
    {
        private readonly RedisService _redisService;
        private readonly TraceabilityRedisHelper _traceabilityRedisHelper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="redisService">Redis服务</param>
        /// <param name="traceabilityRedisHelper">溯源信息Redis帮助类</param>
        public RedisTestController(RedisService redisService, TraceabilityRedisHelper traceabilityRedisHelper)
        {
            _redisService = redisService;
            _traceabilityRedisHelper = traceabilityRedisHelper;
        }

        /// <summary>
        /// 测试Redis连接
        /// </summary>
        /// <returns>连接测试结果</returns>
        [HttpGet]
        public async Task<APIResult<string>> TestConnection()
        {
            var result = new APIResult<string>();
            
            try
            {
                // 测试基本的字符串设置和获取
                string testKey = "test:connection:" + Guid.NewGuid().ToString("N");
                string testValue = "Connection test at " + DateTime.Now.ToString();
                
                // 设置测试值
                bool setResult = await _redisService.StringSetAsync(testKey, testValue, 60);
                
                if (!setResult)
                {
                    result.Code = APIEnum.操作失败;
                    result.Message = "Redis设置值失败";
                    return result;
                }
                
                // 获取测试值
                string getValue = await _redisService.StringGetAsync(testKey);
                
                if (getValue != testValue)
                {
                    result.Code = APIEnum.操作失败;
                    result.Message = $"Redis获取值不匹配: 期望 '{testValue}', 实际 '{getValue}'";
                    return result;
                }
                
                // 删除测试键
                await _redisService.DeleteAsync(testKey);
                
                result.Code = APIEnum.操作成功;
                result.Message = "Redis连接测试成功";
                result.Data = $"成功设置并读取测试值: {testValue}";
            }
            catch (Exception ex)
            {
                result.Code = APIEnum.操作失败;
                result.Message = $"Redis连接测试失败: {ex.Message}";
                if (ex.InnerException != null)
                {
                    result.Data = $"详细错误: {ex.InnerException.Message}";
                }
            }
            
            return result;
        }

        /// <summary>
        /// 测试Redis对象缓存
        /// </summary>
        /// <returns>对象缓存测试结果</returns>
        [HttpGet]
        public async Task<APIResult<TestObject>> TestObjectCache()
        {
            var result = new APIResult<TestObject>();
            
            try
            {
                string testKey = "test:object:" + Guid.NewGuid().ToString("N");
                var testObject = new TestObject
                {
                    Id = 1,
                    Name = "测试对象",
                    CreateTime = DateTime.Now
                };
                
                // 缓存对象
                bool setResult = await _redisService.SetAsync(testKey, testObject, 60);
                
                if (!setResult)
                {
                    result.Code = APIEnum.操作失败;
                    result.Message = "Redis缓存对象失败";
                    return result;
                }
                
                // 获取对象
                var cachedObject = await _redisService.GetAsync<TestObject>(testKey);
                
                if (cachedObject == null)
                {
                    result.Code = APIEnum.操作失败;
                    result.Message = "Redis获取缓存对象失败";
                    return result;
                }
                
                // 删除测试键
                await _redisService.DeleteAsync(testKey);
                
                result.Code = APIEnum.操作成功;
                result.Message = "Redis对象缓存测试成功";
                result.Data = cachedObject;
            }
            catch (Exception ex)
            {
                result.Code = APIEnum.操作失败;
                result.Message = $"Redis对象缓存测试失败: {ex.Message}";
            }
            
            return result;
        }

        /// <summary>
        /// 测试Redis哈希表操作
        /// </summary>
        /// <returns>哈希表操作测试结果</returns>
        [HttpGet]
        public async Task<APIResult<Dictionary<string, string>>> TestHashOperations()
        {
            var result = new APIResult<Dictionary<string, string>>();
            
            try
            {
                string testKey = "test:hash:" + Guid.NewGuid().ToString("N");
                
                // 设置哈希字段
                await _redisService.HashSetAsync(testKey, "field1", "value1");
                await _redisService.HashSetAsync(testKey, "field2", "value2");
                await _redisService.HashSetAsync(testKey, "field3", "value3");
                
                // 获取所有哈希字段
                var hashValues = await _redisService.HashGetAllAsync(testKey);
                
                // 删除测试键
                await _redisService.DeleteAsync(testKey);
                
                result.Code = APIEnum.操作成功;
                result.Message = "Redis哈希表操作测试成功";
                result.Data = hashValues;
            }
            catch (Exception ex)
            {
                result.Code = APIEnum.操作失败;
                result.Message = $"Redis哈希表操作测试失败: {ex.Message}";
            }
            
            return result;
        }
    }

    /// <summary>
    /// 测试对象类
    /// </summary>
    public class TestObject
    {
        /// <summary>
        /// ID
        /// </summary>
        public int Id { get; set; }
        
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }
    }
} 